package dungeons;


import org.junit.Before;
import org.junit.Test;

import dungeons.Shaft.shaftDirection;

import squares.*;
import squares.Square.TemperatureType;
import borders.*;

public class CompositeDungeonTest {
	private static CompositeDungeon<Square> compositeDungeon1,compositeDungeon2;
	private static Square square1;
	@Before
	public void setUp()
	{
		compositeDungeon1 = new CompositeDungeon<Square>(500,500,500);
		compositeDungeon2 = new CompositeDungeon<Square>(100,100,100);
	}
	@Test
	public void testAddSquare() throws IllegalArgumentException, IllegalSquareException, InvalidTemperatureException, InvalidHumidityException, IllegalTemperatureTypeException {
		Shaft<Square> shaft = new Shaft<Square>(50,shaftDirection.X);
		compositeDungeon1.addDungeon(shaft, 11, 10, 10);
		compositeDungeon1.addSquare(new TransparentSquare(100, TemperatureType.CELSIUS, 10, false, false, Direction.NORTH, false), 12, 10, 10);
		assert(compositeDungeon1.getSquareAt(12, 10, 10) != null);
		square1 = new Square(40,TemperatureType.CELSIUS,40,false,false,null,new Open(square1),new Door(square1,true),new Open(square1),null,null);
		compositeDungeon1.addSquare(square1, 13, 10, 10);
		assert(compositeDungeon1.getSquareAt(13, 10, 10) != null);
	}

	@Test
	public void testGetSquareAt() throws InvalidTemperatureException, InvalidHumidityException, IllegalTemperatureTypeException, IllegalArgumentException, IllegalSquareException {
		Shaft<Square> shaft = new Shaft<Square>(50,shaftDirection.X);
		compositeDungeon2.addDungeon(shaft, 11, 10, 10);
		compositeDungeon2.addSquare(new TransparentSquare(100, TemperatureType.CELSIUS, 10, false, false, Direction.NORTH, false), 12, 10, 10);
		assert(compositeDungeon2.getSquareAt(12, 10, 10) != null);
		square1 = new Square(40,TemperatureType.CELSIUS,40,false,false,null,new Open(square1),new Door(square1,true),new Open(square1),null,null);
		compositeDungeon2.addSquare(square1, 13, 10, 10);
		assert(compositeDungeon2.getSquareAt(13, 10, 10) != null);
		compositeDungeon1.addDungeon(compositeDungeon2, 12, 10, 10);
		assert(compositeDungeon1.getSquareAt(25, 20, 20) != null);
	}

	@Test
	public void testDeleteSquare() throws IllegalArgumentException, IllegalSquareException, InvalidTemperatureException, InvalidHumidityException, IllegalTemperatureTypeException {
		Shaft<Square> shaft = new Shaft<Square>(50,shaftDirection.X);
		compositeDungeon2.addDungeon(shaft, 11, 10, 10);
		compositeDungeon2.addSquare(new TransparentSquare(100, TemperatureType.CELSIUS, 10, false, false, Direction.NORTH, false), 11, 10, 10);
		assert(compositeDungeon2.getSquareAt(12, 10, 10) != null);
		square1 = new Square(40,TemperatureType.CELSIUS,40,false,false,null,new Open(square1),new Door(square1,true),new Open(square1),null,null);
		compositeDungeon2.addSquare(square1, 13, 10, 10);
		compositeDungeon2.deleteSquare(13, 10, 10);
		assert(square1.isTerminated());
	}

	@Test(expected = Exception.class)
	public void testAddDungeon() {
		compositeDungeon2.addDungeon(compositeDungeon1, 32, 12, 12);
	}

	@Test
	public void testRemoveDungeonAt() throws IllegalArgumentException, IllegalSquareException, InvalidTemperatureException, InvalidHumidityException, IllegalTemperatureTypeException {
		Shaft<Square> shaft = new Shaft<Square>(50,shaftDirection.X);
		compositeDungeon2.addDungeon(shaft, 11, 10, 10);
		compositeDungeon2.addSquare(new TransparentSquare(100, TemperatureType.CELSIUS, 10, false, false, Direction.NORTH, false), 12, 10, 10);

		square1 = new Square(40,TemperatureType.CELSIUS,40,false,false,null,new Open(square1),new Door(square1,true),new Open(square1),null,null);
		compositeDungeon2.addSquare(square1, 13, 10, 10);
		compositeDungeon1.addDungeon(compositeDungeon2, 12, 10, 10);
		compositeDungeon1.RemoveDungeonAt(12, 10, 10);
		assert(shaft.isTerminated());
		assert(shaft.getDimensions().isEmpty());
		assert(compositeDungeon2.isTerminated());
		assert(compositeDungeon1.getSubDungeonAt(12, 10, 10) == null);
	}
	@Test
	public void testGetRootLocationOfDungeon() {
		Shaft<Square> shaft = new Shaft<Square>(50,shaftDirection.X);
		compositeDungeon2.addDungeon(shaft, 11, 10, 10);
		assert(compositeDungeon2.getRootLocationOfDungeon(shaft)[0] == 11 && compositeDungeon2.getRootLocationOfDungeon(shaft)[1] == 10 && compositeDungeon2.getRootLocationOfDungeon(shaft)[2] == 10);
	}
}
